package com.yugu.util;


import org.apache.commons.collections4.CollectionUtils;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class TreeUtils {
	/**
	 * 	包装成树形结构 (全部属性) 必须要有value pValue children
	 *
	 * @param tree
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public static List factorTree(List tree) {
		try {
			if (tree != null) {
				List t_list = new ArrayList();
				Map map = new HashMap();
				for (Object o : tree) {
					Class clazz = o.getClass();
					Field id = clazz.getDeclaredField("value");
					if (!id.isAccessible()) {
						id.setAccessible(true);
					}
					Long lId = (Long) id.get(o);
					map.put(lId, o);
				}
				for (Object treeItem : tree) {
					Class clazz = treeItem.getClass();
					Field treeItemId = clazz.getDeclaredField("value");
					if (!treeItemId.isAccessible()) {
						treeItemId.setAccessible(true);
					}
					Long cId = (Long) treeItemId.get(treeItem);
					Object obj = map.get(cId);
					
					Field pId = clazz.getDeclaredField("pValue");
					if (!pId.isAccessible()) {
						pId.setAccessible(true);
					}
					Long id = (Long) pId.get(obj);
					if (null == map.get(id)) {
						t_list.add(obj);
					} else {
						Object object = map.get(id);
						Class clazz1 = object.getClass();
						Field children = null;
						try {
							// 没有children属性就到父类查找
							children = clazz1.getDeclaredField("children");
						} catch (Exception e) {
							children = clazz1.getSuperclass().getDeclaredField("children");
						}
						if (!children.isAccessible()) {
							children.setAccessible(true);
						}
						List list = (List) children.get(object);
						if (CollectionUtils.isEmpty(list)) {
							list = new ArrayList<>();
						}
						list.add(obj);
						children.set(object, list);
					}
				}
				return t_list;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	
	
	
	/**
	 * 	包装成树形结构 (全部属性) 必须要有code pCode children
	 *
	 * @param tree
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public static List factorTreeByCode(List tree) {
		try {
			if (tree != null) {
				List t_list = new ArrayList();
				Map map = new HashMap();
				for (Object o : tree) {
					Class clazz = o.getClass();
					Field id = clazz.getDeclaredField("code");
					if (!id.isAccessible()) {
						id.setAccessible(true);
					}
					String lId = (String) id.get(o);
					map.put(lId, o);
				}
				for (Object treeItem : tree) {
					Class clazz = treeItem.getClass();
					Field treeItemId = clazz.getDeclaredField("code");
					if (!treeItemId.isAccessible()) {
						treeItemId.setAccessible(true);
					}
					String cId = (String) treeItemId.get(treeItem);
					Object obj = map.get(cId);
					
					Field pId = clazz.getDeclaredField("pcode");
					if (!pId.isAccessible()) {
						pId.setAccessible(true);
					}
					String id = (String) pId.get(obj);
					if (null == map.get(id)) {
						t_list.add(obj);
					} else {
						Object object = map.get(id);
						Class clazz1 = object.getClass();
						Field children = null;
						try {
							// 没有children属性就到父类查找
							children = clazz1.getDeclaredField("children");
						} catch (Exception e) {
							children = clazz1.getSuperclass().getDeclaredField("children");
						}
						if (!children.isAccessible()) {
							children.setAccessible(true);
						}
						List list = (List) children.get(object);
						if (CollectionUtils.isEmpty(list)) {
							list = new ArrayList<>();
						}
						list.add(obj);
						children.set(object, list);
					}
				}
				return t_list;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	
	
	/**
	 * 	包装成树形结构 (全部属性) 必须要有code pCode children
	 *
	 * @param tree
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public static List factorTreeByValue(List tree) {
		try {
			if (tree != null) {
				List t_list = new ArrayList();
				Map map = new HashMap();
				for (Object o : tree) {
					Class clazz = o.getClass();
					Field id = clazz.getDeclaredField("value");
					if (!id.isAccessible()) {
						id.setAccessible(true);
					}
					String lId = (String) id.get(o);
					map.put(lId, o);
				}
				for (Object treeItem : tree) {
					Class clazz = treeItem.getClass();
					Field treeItemId = clazz.getDeclaredField("value");
					if (!treeItemId.isAccessible()) {
						treeItemId.setAccessible(true);
					}
					String cId = (String) treeItemId.get(treeItem);
					Object obj = map.get(cId);
					
					Field pId = clazz.getDeclaredField("pValue");
					if (!pId.isAccessible()) {
						pId.setAccessible(true);
					}
					String id = (String) pId.get(obj);
					if (null == map.get(id)) {
						t_list.add(obj);
					} else {
						Object object = map.get(id);
						Class clazz1 = object.getClass();
						Field children = null;
						try {
							// 没有children属性就到父类查找
							children = clazz1.getDeclaredField("children");
						} catch (Exception e) {
							children = clazz1.getSuperclass().getDeclaredField("children");
						}
						if (!children.isAccessible()) {
							children.setAccessible(true);
						}
						List list = (List) children.get(object);
						if (CollectionUtils.isEmpty(list)) {
							list = new ArrayList<>();
						}
						list.add(obj);
						children.set(object, list);
					}
				}
				return t_list;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
}

